/*
* $Id$
*
* Copyright 2008 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.io.nio;
import java.awt.Dimension;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import ome.model.core.Pixels;
import ome.util.PixelData;
/**
* Class implementation of the PixelBuffer interface for in memory planar pixel
* data. It does not support indexing the pixel data as one large array as the
* data is underlying modeled as a 5-dimensional array. It is also
* <b>read-only.</b>
*
* @author Chris Allan <a
* href="mailto:chris@glencoesoftware.com">chris@glencoesoftware.com</a>
* @version $Revision$
* @since 3.0
* @see PixelBuffer
*/
public class InMemoryPlanarPixelBuffer implements PixelBuffer
{
/** ZCT ordered planar data. */
private byte[][][][] planes;
/** Pixels object describing the planar data's dimensionality. */
private Pixels pixels;
/**
* Constructs an in memory pixel buffer based on a defined dimensionality.
* @param pixels Dimensionality and pixels type of the planar data.
* @param planes The planar data.
*/
public InMemoryPlanarPixelBuffer(Pixels pixels, byte[][][][] planes)
{
this.pixels = pixels;
this.planes = planes;
}
public byte[] calculateMessageDigest() throws IOException
{
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(
"Required SHA-1 message digest algorithm unavailable.");
}
for (int z = 0; z < getSizeZ(); z++) {
for (int c = 0; c < getSizeC(); c++) {
for (int t = 0; t < getSizeT(); t++) {
try {
ByteBuffer buffer = getPlane(z, c, t).getData();
md.update(buffer);
} catch (DimensionsOutOfBoundsException e) {
throw new RuntimeException(e);
}
}
}
}
return md.digest();
}
public void checkBounds(Integer x, Integer y, Integer z, Integer c,
Integer t)
throws DimensionsOutOfBoundsException
{
if (x != null && (x > getSizeX() - 1 || x < 0)) {
throw new DimensionsOutOfBoundsException("X '" + x
+ "' greater than sizeX '" + getSizeX() + "'.");
}
if (y != null && (y > getSizeY() - 1 || y < 0)) {
throw new DimensionsOutOfBoundsException("Y '" + y
+ "' greater than sizeY '" + getSizeY() + "'.");
}
if (z != null && (z > getSizeZ() - 1 || z < 0)) {
throw new DimensionsOutOfBoundsException("Z '" + z
+ "' greater than sizeZ '" + getSizeZ() + "'.");
}
if (c != null && (c > getSizeC() - 1 || c < 0)) {
throw new DimensionsOutOfBoundsException("C '" + c
+ "' greater than sizeC '" + getSizeC() + "'.");
}
if (t != null && (t > getSizeT() - 1 || t < 0)) {
throw new DimensionsOutOfBoundsException("T '" + t
+ "' greater than sizeT '" + getSizeT() + "'.");
}
}
public void close() throws IOException
{
}
public int getByteWidth()
{
return PixelData.getBitDepth(pixels.getPixelsType().getValue()) / 8;
}
public long getId()
{
throw new NullPointerException("In memory planar buffers have no Id.");
}
public String getPath()
{
throw new NullPointerException("In memory planar buffers have no path.");
}
public Long getHypercubeSize(List<Integer> offset, List<Integer> size,
List<Integer> step) throws DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public PixelData getHypercube(List<Integer> offset, List<Integer> size,
List<Integer> step) throws IOException, DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public byte[] getHypercubeDirect(List<Integer> offset, List<Integer> size,
List<Integer> step, byte[] buffer)
throws IOException, DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public PixelData getPlane(Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException
{
ByteBuffer buf = ByteBuffer.wrap(planes[z][c][t]);
return new PixelData(pixels.getPixelsType().getValue(), buf);
}
public byte[] getPlaneDirect(Integer z, Integer c, Integer t, byte[] buffer)
throws IOException, DimensionsOutOfBoundsException
{
return planes[z][c][t];
}
public Long getPlaneOffset(Integer z, Integer c, Integer t)
throws DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public PixelData getPlaneRegion(Integer x, Integer y, Integer width,
Integer height, Integer z, Integer c, Integer t, Integer stride)
throws IOException, DimensionsOutOfBoundsException
{
return null;
}
public byte[] getPlaneRegionDirect(Integer z, Integer c, Integer t,
Integer count, Integer offset, byte[] buffer) throws IOException,
DimensionsOutOfBoundsException
{
byte[] plane = planes[z][c][t];
int sourceOffset = offset * getByteWidth();
int length = count * getByteWidth();
System.arraycopy(plane, sourceOffset, buffer, 0, length);
return buffer;
}
public Long getPlaneSize()
{
return (long) pixels.getSizeX() * (long) pixels.getSizeY() * getByteWidth();
}
public PixelData getRegion(Integer size, Long offset) throws IOException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public byte[] getRegionDirect(Integer size, Long offset, byte[] buffer)
throws IOException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public PixelData getRow(Integer y, Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException
{
// TODO: This could be supported, we're just not going to right now.
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public PixelData getCol(Integer x, Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException
{
// TODO: This could be supported, we're just not going to right now.
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public byte[] getRowDirect(Integer y, Integer z, Integer c, Integer t,
byte[] buffer) throws IOException, DimensionsOutOfBoundsException
{
// TODO: This could be supported, we're just not going to right now.
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public byte[] getColDirect(Integer x, Integer z, Integer c, Integer t,
byte[] buffer) throws IOException, DimensionsOutOfBoundsException
{
// TODO: This could be supported, we're just not going to right now.
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public Long getRowOffset(Integer y, Integer z, Integer c, Integer t)
throws DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public Integer getRowSize()
{
return getSizeX() * getByteWidth();
}
public Integer getColSize()
{
return getSizeY() * getByteWidth();
}
public int getSizeC()
{
return pixels.getSizeC();
}
public int getSizeT()
{
return pixels.getSizeT();
}
public int getSizeX()
{
return pixels.getSizeX();
}
public int getSizeY()
{
return pixels.getSizeY();
}
public int getSizeZ()
{
return pixels.getSizeZ();
}
public PixelData getStack(Integer c, Integer t) throws IOException,
DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public byte[] getStackDirect(Integer c, Integer t, byte[] buffer)
throws IOException, DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public Long getStackOffset(Integer c, Integer t)
throws DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public Long getStackSize()
{
return getPlaneSize() * pixels.getSizeZ();
}
public PixelData getTimepoint(Integer t) throws IOException,
DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public byte[] getTimepointDirect(Integer t, byte[] buffer)
throws IOException, DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public Long getTimepointOffset(Integer t)
throws DimensionsOutOfBoundsException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public Long getTimepointSize()
{
return getStackSize() * pixels.getSizeC();
}
public Long getTotalSize()
{
return getTimepointSize() * pixels.getSizeT();
}
public boolean isFloat()
{
MappedByteBuffer b = null;
PixelData d = new PixelData(pixels.getPixelsType().getValue(), b);
return d.isFloat();
}
public boolean isSigned()
{
MappedByteBuffer b = null;
PixelData d = new PixelData(pixels.getPixelsType().getValue(), b);
return d.isSigned();
}
public void setPlane(ByteBuffer buffer, Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException,
BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setPlane(byte[] buffer, Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException,
BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setRegion(Integer size, Long offset, byte[] buffer)
throws IOException, BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setRegion(Integer size, Long offset, ByteBuffer buffer)
throws IOException, BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setRow(ByteBuffer buffer, Integer y, Integer z, Integer c,
Integer t) throws IOException, DimensionsOutOfBoundsException,
BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setStack(ByteBuffer buffer, Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException,
BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setStack(byte[] buffer, Integer z, Integer c, Integer t)
throws IOException, DimensionsOutOfBoundsException,
BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setTimepoint(ByteBuffer buffer, Integer t) throws IOException,
DimensionsOutOfBoundsException, BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
public void setTimepoint(byte[] buffer, Integer t) throws IOException,
DimensionsOutOfBoundsException, BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#getTile(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer)
*/
public PixelData getTile(Integer z, Integer c, Integer t, Integer x,
Integer y, Integer w, Integer h) throws IOException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#getTileDirect(java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, byte[])
*/
public byte[] getTileDirect(Integer z, Integer c, Integer t, Integer x,
Integer y, Integer w, Integer h, byte[] buffer) throws IOException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#setTile(byte[], java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer)
*/
public void setTile(byte[] buffer, Integer z, Integer c, Integer t, Integer x, Integer y,
Integer w, Integer h) throws IOException,
BufferOverflowException
{
throw new UnsupportedOperationException(
"Not supported with in memory planar buffers.");
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#getResolutionLevel()
*/
public int getResolutionLevel()
{
return 0;
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#getResolutionLevels()
*/
public int getResolutionLevels()
{
return 1;
}
public List<List<Integer>> getResolutionDescriptions()
{
List<Integer> sizes = Arrays.asList(getSizeX(), getSizeY());
List<List<Integer>> rv = new ArrayList<List<Integer>>();
rv.add(sizes);
return rv;
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#getTileSize()
*/
public Dimension getTileSize()
{
return null;
}
/* (non-Javadoc)
* @see ome.io.nio.PixelBuffer#setResolutionLevel(int)
*/
public void setResolutionLevel(int resolutionLevel)
{
throw new UnsupportedOperationException(
"Cannot set resolution levels on an in memory pixel buffer.");
}
}